#ifndef BLOCK_CONFIG_H
#define BLOCK_CONFIG_H

#include <muduo/base/Types.h>
#include <muduo/base/Logging.h>
#include <fstream>
#include <assert.h>
#include <pthread.h>
#include <list>

#include <boost/noncopyable.hpp>

#include <sdfs/config/Json.h>
#include <sdfs/common/ToolKit.h>
#include <sdfs/storage/Block.h>
#include <sdfs/storage/BlockStatus.h>

using namespace muduo;

namespace sdfs
{
namespace storage
{

class BlockStatusConfig: public boost::noncopyable
{

private:
	BlockStatusConfig( )
	{
		
	}
public:
	static sdfs::storage::BlockStatusPtr parse(
		const muduo::string &fullname, 
		sdfs::storage::BlockPtr block)
	{
		sdfs::JsonValuePtr tree = sdfs::JsonHelper::ParseJson(fullname);
		LOG_DEBUG << "status: " << fullname << ", found: " << tree!=NULL?"true":"false";
		if(tree == NULL)
		{
			sdfs::storage::BlockStatusPtr status(
				new BlockStatus(block->getIndex(), block, capacity));
			SaveStatus(fullname, status);
			return status;
		}
		int idx = (*tree)["id"].asInt();
		int capacity = (*tree)["blockcapacityMB"].asInt();//MB
		sdfs::storage::BlockStatusPtr status(new BlockStatus(idx, block, capacity));
		Json::Value pieces = (*tree)["freepieces"];
		long freesize = 0;
		for(uint32_t i = 0 ; i < pieces.size() ; ++i)
		{
			long offset= pieces[i]["offset"].asInt();
			long length = trackerRoot[i]["port"].asInt();
			freesize += length;
			PiecePtr piece(new Piece(idx, offset, length));
			status->addFreePiece(piece);
		}
		status->setFreeSize(freesize);
		return status;
	}

	static void SaveStatus(muduo::string& path, 
		const sdfs::storage::BlockStatusPtr status)
	{
		Json::Value root;
		root["id"] = status->getIndex();
		root["blockcapacityMB"] = status->getCapacity();
		root["freesize"] = status->getFreeSize();
		Json::Value freepiece = (Json::arrayValue);
		std::list<PiecePtr>* pieces = status->getPieces();
		std::list<PiecePtr>::iterator it;
		for (it = pieces->begin(); it != pieces->end(); it++)
		{
			Json::Value piece;
			piece["offset"] = status->getOffset();
			piece["length"] = status->getLength();
    			freepiece.append(piece);
		}
		root["freepiece"] = freepiece;
		char buf[256];
		snprintf(buf, 256, "%s/%d.status", path.c_str(), status->getIndex());
		muduo::string fullname(buf);
		JsonHelper::SerilizeJson(fullname, root);
	}

	
	~BlockStatusConfig(){}


};

}
}

#endif